# 二、函数中的参数

# 1、必要传参，也叫位置参数
# 定义函数时，根据需求必需要传递的参数， 而且，在调用函数时根据函数定义的参数位置顺序来传递参数。
# 注意：传递和定义参数的顺序及个数必须一致。
def test1(x, y):
    return x + y


print(test1(1, 2))  # 输出 3


# 2、关键字传参
# 函数调用，通过“键=值”形式加以指定。可以让函数更加清晰、容易使用，同时也清除了参数的顺序需求。
# 注意： 函数调用时，如果有位置参数时，位置参数必须在关键字参数的前面，但关键字参数之间不存在先后顺序。
# print(test1(y=10, x=20)) # 输出 30

def test1(a, x, y):  # 这种 注意： 函数调用时，如果有位置参数时，位置参数必须在关键字参数的前面，但关键字参数之间不存在先后顺序。
    return x + y


print(test1(1, y=10, x=20))


# 3、默认值传参
# 用于定义函数，为参数提供默认值，调用函数时可不传该默认参数的值（注意：所有位置参数必须出现在默认参数前，包括函数定义和调用）。
def test2(x, y, init_sum=10):
    init_sum += x + y
    return init_sum


print(test2(10, 20))  # 输出 40
print(test2(10, 20, 20))  # 输出 50


# 4、不定长传参
# 不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时，来进行参数传递，会显得非常方便。
# 1. 不定长普通参数
def test3(*args, init_sum=10):
    """
    测试不定长传参函数
    :param args: 不定长参数,本质上是元组 tuple
    :param init_sum: 默认值传参 10
    :return: 返回整数累加
    """
    print(init_sum)
    print(type(args))  # 输出 <class 'tuple'>
    print(args)  # args 不传参数 输出 ()
    if args:  # args这个参数 是元组 默认是空元组, 这里可以做条件判断.  python中 空值,0,NULL 做条件判断都是false
        for arg in args:
            init_sum += arg
    return init_sum


def test4(*args, init_sum=10):
    """
    简便写法 测试  return init_sum + sum(args)  # 输出 16
    :param args:
    :param init_sum:
    :return:
    """
    print(init_sum)
    print(type(args))
    print(args)
    if args:
        return init_sum + sum(args)  # 输出 16
    return init_sum  # 输出 10


print(test4)
print(test4(1, 2, 3))

print('*' * 50)


def test5(init_sum=10, **kwargs):
    """
    测试 不定长传参 不定长关键字参数
    :param init_sum:
    :param kwargs: 字典
    :return: 返回 传递的参数累加 (init_sum + kwargs的values的和)
    """
    print(type(kwargs))
    for key, value in kwargs.items():
        print(f'{key}:{value}')
    return init_sum + sum(kwargs.values())


print(test5(x=10, y=20))
print('*' * 50)
print(test5(x=10, y=20, init_sum=30))



#  位置参数---> 默认传承-->不定长普通参数--->不定长关键字参数
# def test5(a, b, c=100, *args, **kwargs):
